2020-2021 Sunseeker Telemetry and Lighting System
timer_d_ex10_dutyCycleMeasurementDual.c
Go to the documentation of this file.
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 //******************************************************************************
33 // MSP430F51x2 Demo - TimerD0, Dual Input Capture mode, Normal Timer Mode,
34 // Input Dutycycle measurement
35 // Description: This code example implements input capture in dual capture
36 // mode using TimerD in normal timer mode. TD1.1 is configured to output PWM
37 // of 25% dutycycle, that is used as capture input to TD0.1. TD0.1 is
38 // configured as timer input capture and is triggered by both the rising and
39 // falling edges. An external connection between TD1.1 and TD0.1 is required.
40 // Rising and Falling edges are captured in the dual capture mode and the
41 // Period and Dutycycle is computed. If the measured dutycycle is != 25%, then
42 // LED on P1.0 is set.
43 //
44 // ACLK = LFXT1 = 32kHz; SMCLK = MCLK = 2.45MHz;
45 //
46 // MSP430F51x2
47 // -----------------
48 // /|\| XIN|-
49 // | | | 32kHz
50 // --|RST XOUT|-
51 // | |
52 // | P1.7/TD0.1|<-- CCI1A <-|
53 // | P2.2/TD1.1|--> CCR1 -->|
54 // | |
55 // | P1.0|--> LED "ON" if measured Dutycycle != 25%
56 // | |
57 //
58 //******************************************************************************
59 #include "driverlib.h"
60 
61 uint8_t Count = 0x0;
62 uint16_t REdge1, REdge2, FEdge1, FEdge2;
63 uint16_t Period, ON_Period;
64 uint8_t DutyCycle;
65 
66 void main(void)
67 {
68  // Stop watchdog timer
69  WDT_A_hold(WDT_A_BASE);
70 
71  // P1.0/LED Output
72  // LED off
73  GPIO_setAsOutputPin(
74  GPIO_PORT_P1,
75  GPIO_PIN0
76  );
77 
79  GPIO_PORT_P1,
80  GPIO_PIN0
81  );
82 
83  // Configure XT1
84  // Port select XT1
85  GPIO_setAsPeripheralModuleFunctionInputPin(
86  GPIO_PORT_PJ,
87  GPIO_PIN4 + GPIO_PIN5
88  );
89 
90  UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,
91  UCS_XCAP_3);
92 
93  // Initialize DCO to 2.45MHz
94  // (74 + 1) * 32768 = 2.45MHz
95  UCS_initFLLSettle(2450,
96  74);
97 
98 
99  // Configure Port Pins
100  GPIO_setAsPeripheralModuleFunctionInputPin(
101  GPIO_PORT_P1,
102  GPIO_PIN7
103  );
104 
105  GPIO_setAsPeripheralModuleFunctionOutputPin(
106  GPIO_PORT_P2,
107  GPIO_PIN2
108  );
109 
110  // Configure TD1.1 to output PWM signal
111  Timer_D_initCompareModeParam initCompParam = {0};
112  initCompParam.compareRegister = TIMER_D_CAPTURECOMPARE_REGISTER_1;
113  initCompParam.compareInterruptEnable = TIMER_D_CAPTURECOMPARE_INTERRUPT_DISABLE;
114  initCompParam.compareOutputMode = TIMER_D_OUTPUTMODE_RESET_SET;
115  initCompParam.compareValue = 21;
116  Timer_D_initCompareMode(TIMER_D1_BASE, &initCompParam);
117 
118  Timer_D_initUpModeParam initUpParam = {0};
119  initUpParam.clockSource = TIMER_D_CLOCKSOURCE_ACLK;
120  initUpParam.clockSourceDivider = TIMER_D_CLOCKSOURCE_DIVIDER_1;
121  initUpParam.clockingMode = TIMER_D_CLOCKINGMODE_EXTERNAL_CLOCK;
122  initUpParam.timerPeriod = 82-1;
123  initUpParam.timerInterruptEnable_TDIE = TIMER_D_TDIE_INTERRUPT_DISABLE;
124  initUpParam.captureCompareInterruptEnable_CCR0_CCIE =
125  TIMER_D_CAPTURECOMPARE_INTERRUPT_DISABLE;
126  initUpParam.timerClear = TIMER_D_DO_CLEAR;
127  Timer_D_initUpMode(TIMER_D1_BASE, &initUpParam);
128 
129  Timer_D_startCounter(TIMER_D1_BASE,
130  TIMER_D_UP_MODE
131  );
132 
133  Timer_D_initContinuousModeParam initContParam = {0};
134  initContParam.clockSource = TIMER_D_CLOCKSOURCE_SMCLK;
135  initContParam.clockSourceDivider = TIMER_D_CLOCKSOURCE_DIVIDER_1;
136  initContParam.clockingMode = TIMER_D_CLOCKINGMODE_EXTERNAL_CLOCK;
137  initContParam.timerInterruptEnable_TDIE = TIMER_D_TDIE_INTERRUPT_DISABLE;
138  initContParam.timerClear = TIMER_D_DO_CLEAR;
139  Timer_D_initContinuousMode(TIMER_D0_BASE, &initContParam);
140 
141  Timer_D_startCounter(TIMER_D0_BASE,
142  TIMER_D_CONTINUOUS_MODE
143  );
144 
145  Timer_D_clearCaptureCompareInterrupt(TIMER_D0_BASE,
146  TIMER_D_CAPTURECOMPARE_REGISTER_1);
147 
148  Timer_D_initCaptureModeParam initCapParam = {0};
149  initCapParam.captureRegister = TIMER_D_CAPTURECOMPARE_REGISTER_1;
150  initCapParam.captureMode = TIMER_D_CAPTUREMODE_RISING_AND_FALLING_EDGE;
151  initCapParam.captureInputSelect = TIMER_D_CAPTURE_INPUTSELECT_CCIxA;
152  initCapParam.synchronizeCaptureSource = TIMER_D_CAPTURE_SYNCHRONOUS;
153  initCapParam.captureInterruptEnable = TIMER_D_CAPTURECOMPARE_INTERRUPT_ENABLE;
154  initCapParam.captureOutputMode = TIMER_D_OUTPUTMODE_OUTBITVALUE;
155  initCapParam.channelCaptureMode = TIMER_D_DUAL_CAPTURE_MODE;
156  Timer_D_initCaptureMode(TIMER_D0_BASE, &initCapParam);
157 
158  while(1)
159  {
160  __bis_SR_register(LPM0_bits + GIE); // Enter LPM0
161  __no_operation(); // For debugger
162  // On exiting LPM0
163  if (TIMER_D_CAPTURE_OVERFLOW == Timer_D_getCaptureCompareInterruptStatus
164  (TIMER_D0_BASE,
165  TIMER_D_CAPTURECOMPARE_REGISTER_1,
166  TIMER_D_CAPTURE_OVERFLOW
167  ) ) // Check for Capture Overflow
168  while(1); // Loop Forever
169 
170  Period = REdge2 - REdge1; // Calculate Period
171  ON_Period = FEdge1-REdge1; // On period
172  DutyCycle = ((uint32_t)ON_Period*100/Period);
173  if(DutyCycle!= 25)
174  {
176  GPIO_PORT_P1,
177  GPIO_PIN0
178  );
179  }
180  }
181 }
182 
183 // TD0_D1 Interrupt vector
184 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
185 #pragma vector=TIMER0_D1_VECTOR
186 __interrupt
187 #elif defined(__GNUC__)
188 __attribute__((interrupt(TIMER0_D1_VECTOR)))
189 #endif
190 void TIMER0_D1_ISR (void)
191 {
192  switch(__even_in_range(TD0IV,0x1E))
193  {
194  case 0x0: break; // Vector 0: No interrupt
195  case 0x2: // Vector 2: TDCCR1 CCIFG
196  if(!Count)
197  {
198  FEdge1 = // 1st falling edge
199  Timer_D_getCaptureCompareCount(TIMER_D0_BASE,
200  TIMER_D_CAPTURECOMPARE_REGISTER_1);
201  REdge1 = // 1st rising edge
202  Timer_D_getCaptureCompareLatchCount(TIMER_D0_BASE,
203  TIMER_D_CAPTURECOMPARE_REGISTER_1);
204  Count++;
205  }
206  else
207  {
208  REdge2 = // 2nd rising edge
209  Timer_D_getCaptureCompareLatchCount(TIMER_D0_BASE,
210  TIMER_D_CAPTURECOMPARE_REGISTER_1);
211  FEdge2 = // Dummy Read
212  Timer_D_getCaptureCompareCount(TIMER_D0_BASE,
213  TIMER_D_CAPTURECOMPARE_REGISTER_1);
214  Count = 0x0;
215  __bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main
216  }
217  break;
218  case 0x4: break; // Vector 4: TDCCR2 CCIFG
219  case 0x6: break; // Vector 6: TDCCR3 CCIFG
220  case 0x8: break; // Vector 8: TDCCR4 CCIFG
221  case 0xA: break; // Vector 10: TDCCR5 CCIFG
222  case 0xC: break; // Vector 12: TDCCR5 CCIFG
223  case 0xE: break; // Vector 14: -
224  case 0x10:break; // Vector 16: TDIFG
225  case 0x12:break; // Vector 18: TDHINT TDHFLIFG
226  case 0x14:break; // Vector 20: TDHINT TDHFHIFG
227  case 0x16:break; // Vector 22: TDHINT TDHLKIFG
228  case 0x18:break; // Vector 24: TDHINT TDHUNLKIFG
229  case 0x1A:break; // Vector 26: -
230  case 0x1C:break; // Vector 28: -
231  case 0x1E:break; // Vector 28: -
232  default: break;
233  }
234 }
235 
__no_operation()
__bic_SR_register_on_exit(LPM3_bits|GIE)
GPIO_setOutputHighOnPin(GPIO_PORT_LED1|GPIO_PORT_LED2, GPIO_PIN_LED1|GPIO_PIN_LED2)
GPIO_setOutputLowOnPin(GPIO_PORT_LED1|GPIO_PORT_LED2, GPIO_PIN_LED1|GPIO_PIN_LED2)